package com.lipaluma.io;

import java.util.ArrayList;
import java.util.List;

import com.lipaluma.parser.marshalling.FieldMarshalled;
import com.lipaluma.parser.marshalling.ObjectMarshalled;
import com.lipaluma.parser.marshalling.OneToManyFieldMarshalled;

public abstract class OneToManyColumnSourceWriter implements SourceWriter {

	@Override
	public void write(ObjectMarshalled objectMarshalled) {
		Row row = createNewEmtpyRow();
		for(FieldMarshalled fieldMarshalled : objectMarshalled.getFieldsMarshalled())
			row.writeValue(fieldMarshalled.getValue(), fieldMarshalled.getMapping());
		createOneToManyRows(objectMarshalled, row);
	}

	public void createOneToManyRows(ObjectMarshalled objectMarshalled, Row row) {
		ArrayList<Row> rows = new ArrayList<Row>();
		rows.add(row);
		createOneToManyRows(objectMarshalled, rows);
	}
	public void createOneToManyRows(ObjectMarshalled objectMarshalled, List<Row> rows) {
		for (OneToManyFieldMarshalled oneToManyFieldMarshalled : objectMarshalled.getOneToManyFieldsMarshalled()) {
			List<List<Row>> listOfRowsToWork = new ArrayList<List<Row>>();
			listOfRowsToWork.add(rows);
			List<ObjectMarshalled> valuesMarshalled = oneToManyFieldMarshalled.getObjectsValuesMarshalled();
			for(int i=0; i<valuesMarshalled.size() - 1; i++)
				listOfRowsToWork.add(duplicateRows(rows));
			for (int i=0; i<valuesMarshalled.size(); i++) {
				List<Row> rowsToWork = listOfRowsToWork.get(i);
				ObjectMarshalled singleValue = valuesMarshalled.get(i);
				for (Row row : rowsToWork) {
					for(FieldMarshalled fieldMarshalled : singleValue.getFieldsMarshalled())
						row.writeValue(fieldMarshalled.getValue(), fieldMarshalled.getMapping());
				}
				createOneToManyRows(singleValue, rowsToWork);
				if(i > 0)
					rows.addAll(rowsToWork);
			}
		}

	}
	
	protected abstract Row createNewEmtpyRow();
	protected abstract List<Row> duplicateRows(List<Row> rows);
}
